package com.study.jvm.reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

/**
 * [深入探讨 java\.lang\.ref 包](https://www.ibm.com/developerworks/cn/java/j-lo-langref/index.html)
 * Description:
 * User: tan
 * DateTime: 2017/9/28 21:19
 */
public class ReferenceTest {
    public static void main(String[] args) {
        //系统在内存溢出异常之前，回收软引用的对象
        SoftReference<Integer> softReference = new SoftReference<Integer>(10);
        System.out.println(softReference.get());


        //只要系统发生内存回收，弱引用对象就被回收。
        WeakReference<Integer> weakReference = new WeakReference<Integer>(20);
        System.out.println(weakReference.get());//20
        System.gc();
        //为什么不是null????
        System.out.println(weakReference.get());//20

        WeakReference<Point> pointWeakReference = new WeakReference<Point>(new Point(10, 20));
        System.out.println(pointWeakReference.get());//point对象
        System.gc();
        //为什么这个是null了？？
        System.out.println(pointWeakReference.get());//null

        //虚引用 无法通过get()方法获取引用的对象，get()返回的总是null
        //主要用来跟踪被内存回收的状态
        //虚引用 的对象不会主动的被系统回收，需要手动处理。
        //PhantomReference 类似强引用，它不会自动根据内存情况自动对目标对象回收，
        ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
        PhantomReference<String> phantomReference = new PhantomReference<>(new String("ceshi"), referenceQueue);
        System.gc();
        System.out.println(referenceQueue.poll() == phantomReference); //true

        ReferenceQueue<String> referenceQueue1 = new ReferenceQueue<>();
        PhantomReference<String> phantomReference1 = new PhantomReference<>("ceshi", referenceQueue);
        System.gc();
        //为什么是 false
        System.out.println(referenceQueue1.poll() == phantomReference1);//false

    }

    static class Point {
        private int x;
        private int y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
}
